package indi.zhifa.study2025.oa.service.user.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import indi.zhifa.engine.core.common.entity.web.ServiceException;
import indi.zhifa.study2025.oa.dao.gen.service.*;
import indi.zhifa.study2025.oa.dao.po.*;
import indi.zhifa.study2025.oa.model.expose.user.dto.UpdateUserDto;
import indi.zhifa.study2025.oa.service.user.IUserService;
import indi.zhifa.study2025.oa.service.user.dto.ChangeStatusDto;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Component
public class UserServiceImpl implements IUserService {

    final IGenUserDbService mGenUserDbService;
    final IGenRoleDbService mGenRoleDbService;
    final IGenDepartmentDbService mGenDepartmentDbService;
    final IGenRelUserRoleDbService mGenRelUserRoleDbService;
    final IGenRelUserPositionDbService mGenRelUserPositionDbService;
    final IGenRelUserDepDbService mGenRelUserDepDbService;
    final IGenPositionDbService mGenPositionDbService;

    @Override
    public boolean exists(String username) {
        LambdaQueryWrapper queryWrapper = Wrappers.<GenUserEntity>lambdaQuery()
                .eq(GenUserEntity::getUserName, username);
        return mGenUserDbService.exists(queryWrapper);
    }

    @Override
    public GenUserEntity save(GenUserEntity pUserEntity) {
        boolean success = mGenUserDbService.save(pUserEntity);
        if(success) {
            return pUserEntity;
        }
        return null;
    }

    @Override
    public GenUserEntity update(Long pId, Object pUpdateUserDto) {
        GenUserEntity userEntity = mGenUserDbService.updatePull(pId, pUpdateUserDto);
        return userEntity;
    }

    protected GenUserEntity check(Long pId){

        GenUserEntity userEntity = mGenUserDbService.checkMin(pId);
        if(null == userEntity){
            throw new ServiceException("没找到Id为"+pId+"的用户");
        }
        return userEntity;
    }

    @Override
    public List<GenRelUserRoleEntity> setRoles(Long pUserId, List<Long> roleIds) {
        if(CollectionUtils.isEmpty(roleIds)){
            return null;
        }

        GenUserEntity userEntity = check(pUserId);

        LambdaUpdateWrapper<GenRelUserRoleEntity> updateWrapper = Wrappers.<GenRelUserRoleEntity>lambdaUpdate()
                .eq(GenRelUserRoleEntity::getUserId, pUserId);
        mGenRelUserRoleDbService.remove(updateWrapper);

        LambdaQueryWrapper<GenRoleEntity> roleCheckQueryWrapper = Wrappers.<GenRoleEntity>lambdaQuery()
                .in(GenRoleEntity::getId, roleIds)
                .select(GenRoleEntity::getId,GenRoleEntity::getCode,GenRoleEntity::getGroupCode);
        List<GenRoleEntity> roleEntityList = mGenRoleDbService.list(roleCheckQueryWrapper);
        Map<Long,GenRoleEntity> roleMap = roleEntityList.stream().collect(Collectors.toMap(GenRoleEntity::getId, v->v));
        if(roleEntityList.size() < roleIds.size()) {
            List<Long> missIds = roleIds.stream().filter(roleId -> !roleMap.containsKey(roleId)).collect(Collectors.toList());
            throw new ServiceException("角色Id"+ StrUtil.join(",", missIds)+"数据丢失");
        }
        // 校验角色组的角色是否唯一
        Map<String,Integer> roleCntMap = new HashMap<>();
        List<String> dupRoleGroupList = new ArrayList<>();
        for(GenRoleEntity roleEntity : roleEntityList) {
            String roleGroupCode = roleEntity.getGroupCode();
            Integer cnt = roleCntMap.get(roleGroupCode);
            if(cnt == null) {
                cnt = 0;
            }
            cnt++;
            if(cnt >= 2){
                dupRoleGroupList.add(roleGroupCode);
            }
            roleCntMap.put(roleGroupCode, cnt);
        }
        if(dupRoleGroupList.size() > 0) {
            throw new ServiceException("每个角色组中的角色只能绑定一个，"+StrUtil.join(",", dupRoleGroupList)+"这些角色组出现的重复情况");
        }

        List<GenRelUserRoleEntity> newRelList = new ArrayList<>();
        for(Long roleId : roleIds) {
            GenRoleEntity relRoleEntity = roleMap.get(roleId);
            GenRelUserRoleEntity newRel = new GenRelUserRoleEntity();
            newRel.createInit();
            newRel.setRoleId(relRoleEntity.getId());
            newRel.setRoleGroupId(relRoleEntity.getGroupId());
            newRel.setRoleGroupCode(relRoleEntity.getGroupCode());
            newRel.setUserId(pUserId);
            newRel.setUserName(userEntity.getUserName());
            newRelList.add(newRel);
        }
        mGenRelUserRoleDbService.saveBatch(newRelList);
        return newRelList;
    }

    @Override
    public List<GenRelUserDepEntity> setDeps(Long pUserId, List<Long> depIds) {

        if(CollectionUtils.isEmpty(depIds)){
            return null;
        }

        GenUserEntity userEntity = check(pUserId);

        LambdaUpdateWrapper<GenRelUserDepEntity> updateWrapper = Wrappers.<GenRelUserDepEntity>lambdaUpdate()
                .eq(GenRelUserDepEntity::getUserId, pUserId);
        mGenRelUserDepDbService.remove(updateWrapper);

        LambdaQueryWrapper<GenDepartmentEntity> depQueryWrapper = Wrappers.<GenDepartmentEntity>lambdaQuery()
                .in(GenDepartmentEntity::getId, depIds)
                .select(GenDepartmentEntity::getId,GenDepartmentEntity::getCode,GenDepartmentEntity::getCodeCascade,GenDepartmentEntity::getName);
        List<GenDepartmentEntity> departmentEntityList = mGenDepartmentDbService.list(depQueryWrapper);
        Map<Long,GenDepartmentEntity> depMap = departmentEntityList.stream().collect(Collectors.toMap(GenDepartmentEntity::getId, v->v));
        if(departmentEntityList.size() < depIds.size()) {
            List<Long> missIds = depIds.stream().filter(depId -> !depMap.containsKey(depId)).collect(Collectors.toList());
            throw new ServiceException("部门Id"+ StrUtil.join(",", missIds)+"数据丢失");
        }

        List<GenRelUserDepEntity> newRelList = new ArrayList<>();
        for(Long depId : depIds) {
            GenDepartmentEntity depEntity = depMap.get(depId);
            GenRelUserDepEntity newRel = new GenRelUserDepEntity();
            newRel.createInit();
            newRel.setDepId(depId);
            newRel.setDepName(depEntity.getName());
            newRel.setDepCode(depEntity.getCode());
            newRel.setDepCodeCascade(depEntity.getCodeCascade());
            newRel.setUserId(pUserId);
            newRel.setUserName(userEntity.getUserName());
            newRelList.add(newRel);
        }
        mGenRelUserDepDbService.saveBatch(newRelList);
        return newRelList;
    }

    @Override
    public List<GenRelUserPositionEntity> setPositions(Long pUserId, List<Long> positionIds) {

        if(CollectionUtils.isEmpty(positionIds)){
            return null;
        }

        GenUserEntity userEntity = check(pUserId);

        LambdaUpdateWrapper<GenRelUserPositionEntity> updateWrapper = Wrappers.<GenRelUserPositionEntity>lambdaUpdate()
                .eq(GenRelUserPositionEntity::getUserId, pUserId);
        mGenRelUserPositionDbService.remove(updateWrapper);

        LambdaQueryWrapper<GenPositionEntity> positionQueryWrapper = Wrappers.<GenPositionEntity>lambdaQuery()
                .eq(GenPositionEntity::getId, positionIds)
                .select(GenPositionEntity::getId,GenPositionEntity::getName);

        List<GenPositionEntity> positionEntityList = mGenPositionDbService.list(positionQueryWrapper);
        Map<Long,GenPositionEntity> positionMap = positionEntityList.stream().collect(Collectors.toMap(GenPositionEntity::getId, v->v));

        if(positionEntityList.size() < positionIds.size()) {
            List<Long> missIds = positionIds.stream().filter(positionId -> !positionMap.containsKey(positionId)).collect(Collectors.toList());
            throw new ServiceException("职位Id"+ StrUtil.join(",", missIds)+"数据丢失");
        }

        List<GenRelUserPositionEntity> newRelList = new ArrayList<>();
        for(Long positionId : positionIds) {
            GenPositionEntity positionEntity = positionMap.get(positionId);
            GenRelUserPositionEntity newRel = new GenRelUserPositionEntity();
            newRel.createInit();
            newRel.setPositionId(positionId);
            newRel.setPositionName(positionEntity.getName());
            newRel.setUserId(userEntity.getId());
            newRel.setUserName(userEntity.getUserName());
            newRelList.add(newRel);
        }
        mGenRelUserPositionDbService.saveBatch(newRelList);
        return newRelList;
    }

    @Override
    public boolean changeStatus(Long pUserId, ChangeStatusDto pChangeStatusDto) {
        check(pUserId);
        GenUserEntity updateUser = new GenUserEntity();
        updateUser.updateInit();
        updateUser.setId(pUserId);
        BeanUtils.copyProperties(pChangeStatusDto,updateUser);
        return mGenUserDbService.updateById(updateUser);
    }

    @Override
    public GenUserEntity checkById(Long pUserId) {
        return mGenUserDbService.check(pUserId);
    }
}
